Skip to content

Conversation

@Cramsden
Copy link
Contributor

@Cramsden Cramsden commented Nov 4, 2025

💡 Description

Running iOS 26 on an iphone SE and an iphone 18 I was able to reproduce a decent amount of hangs around opening the tab tray and opening a tab.

Screenshot 2025-11-03 at 12 47 29 PM Screenshot 2025-11-03 at 9 32 29 PM

I don't know if these changes will actually work

🎥 Demos

Before After
Demo

📝 Checklist

  • I filled in the ticket numbers and a description of my work
  • I updated the PR name to follow our PR naming guidelines
  • I ensured unit tests pass and wrote tests for new code
  • If working on UI, I checked and implemented accessibility (Dynamic Text and VoiceOver)
  • If adding telemetry, I read the data stewardship requirements and will request a data review
  • If adding or modifying strings, I read the guidelines and will request a string review from l10n
  • If needed, I updated documentation and added comments to complex code

}

updateTabCountUsingTabManager(tabManager, animated: false)
updateToolbarStateForTraitCollection(traitCollection)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't actually know if we can remove this call from the viewWillAppear but we are calling this in traitCollectionDidChange as well so maybe we don't need it here?

Comment on lines -4486 to -4487
} else if isSwipingTabsEnabled {
addressToolbarContainer.updateSkeletonAddressBarsVisibility(tabManager: tabManager)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

traitCollectionDidChange gets triggered every time we open a tab which calls updateSkeletonAddressBarsVisibility so maybe we don't need this here as well?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember that this code was added here to help us keep track of the previous and next tab to be able to pre configure the skeleton bars.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PARAIPAN9 Maybe you could help me figure out the right way to clean up this code since you understand the functionality that updateSkeletonAddressBarsVisibility was trying to solve. We have a common pattern in the code of just calling something everywhere so that we can guarantee it was called. We shouldn't need to recalculate this 4 times for each webview though. Prior to this change this function is called:

  • Browser View Controller viewWillAppear
  • Browser View Controller traitCollectionDidChange (this gets called twice when we select a tab)
  • Browser View Controller delegate completion for selecting a tab.

When we select a tab all of these are called.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I will take a look as soon as possible.

do {
lock.lock()
defer { lock.unlock() }
try sessionData.write(to: path, options: .atomicWrite)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to lock if this work is isolated to the main actor

Comment on lines +13 to +19
@MainActor
func saveTabSession(tabID: UUID, sessionData: Data)

/// Fetches the session data associated with a tab
/// - Parameter tabID: an ID that uniquely identifies the tab
/// - Returns: the data associated with a session, encoded as a Data object
@MainActor
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically this work should probably be asynchronous but it will require more thought since we need the tab session to load the webview

Comment on lines 205 to 206
let previousTab = tabs[safe: tabManager.selectedIndex]
let forwardTab = tabs[safe: tabManager.selectedIndex]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change breaks the intended behavior of the skeleton bars. The skeleton bars should be preconfigured to reflect the previous or next tab's state when a user starts swiping left or right. By configuring the skeleton bars to match the current tab, we incorrectly display the current tab's configuration for both the previous and next skeleton bars, even when those tabs are nil.

We might be able to solve the problem by adding:
let previousTab = tabs[safe: tabManager.selectedIndex-1]
let forwardTab = tabs[safe: tabManager.selectedIndex+1]

But looking further to tabManager.selectedIndex I see that is obtained by calling firstIndex(of: ) which has the same O(n) complexity as firstIndex(where:) and I dare to say that in this case, changing from firstIndex(where:) is even slower because here we check for the same reference instead of comparing semantics.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes:

let previousTab = tabs[safe: tabManager.selectedIndex-1]
let forwardTab = tabs[safe: tabManager.selectedIndex+1]

I guess the difference here is that we are leveraging the selectedIndex instead of recalculating it. It already gets set as a side effect of selecting a tab. It is possible we could be smarter when setting the selectedIndex as well!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That being said I really doubt that this is the piece that is causing the lag and the bigger problem is causing this function multiple times but there is no need to recalculate the tab index if we already have it.

Comment on lines -4486 to -4487
} else if isSwipingTabsEnabled {
addressToolbarContainer.updateSkeletonAddressBarsVisibility(tabManager: tabManager)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember that this code was added here to help us keep track of the previous and next tab to be able to pre configure the skeleton bars.

@Cramsden Cramsden requested a review from dataports November 4, 2025 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants